#include <AgentI.h>

AgentI::AgentI
(Ice::Identity name,
 Ice::ObjectAdapterPtr oa):
  _name(name),
  _state(FIPA::Initiated),
  _destroyed(false)
{
  // Well-known services.
  _ams = FIPA::AMSPrx::checkedCast(oa->getCommunicator()->stringToProxy("AMS"));
  _mts = FIPA::MTSPrx::checkedCast(oa->getCommunicator()->stringToProxy("MTS"));
  _df = FIPA::DFPrx::checkedCast(oa->getCommunicator()->stringToProxy("DF"));
  
  FIPA::AgentPrx proxy = FIPA::AgentPrx::uncheckedCast(oa->createIndirectProxy(_name));
  
  // Register with the AMS and DF.
  try {
    _ams->_cpp_register(proxy);
  }
  catch (FIPA::AgentExists& ex) {
    cout << ex << endl;
  }
  
  try {
    FIPA::DfAgentDescription desc;
    desc.name = proxy;
    _df->_cpp_register(desc);
    _df->subscribe(proxy);
  }
  catch (FIPA::AgentExists& ex) {
    cout << ex << endl;
  }
  catch (FIPA::AlreadySubscribed& ex) {
    cout << ex << endl;
  }
}
 
AgentI::~AgentI()
{
}

void
AgentI::setState
(FIPA::AgentState st, 
 const Ice::Current& curr)
{
  IceUtil::Mutex::Lock lock(_m);
  _state = st;
}
 
FIPA::AgentState
AgentI::getState
(const Ice::Current& curr)
{
  IceUtil::Mutex::Lock lock(_m);
  return _state;
}
 
void
AgentI::receiveMessage
(const FIPA::Message& m, 
 const Ice::Current& curr)
{
  //cout << curr.id.name << " received a message from " << m.env.frm->ice_toString() << endl;

  IceGrid::QueryPrx query;
  Test::SnifferPrx sniffer;

  for (int j = 0; j < 10; ++j);

  if (m.payload.content == "beginning") {
    query = IceGrid::QueryPrx::
      uncheckedCast(curr.adapter->getCommunicator()->stringToProxy("FIPA/Query"));
    sniffer = Test::SnifferPrx::
      uncheckedCast(query->findObjectById
		    (curr.adapter->getCommunicator()->stringToIdentity("Sniffer")));
    sniffer->beginTest("user");
  }

  if (m.payload.content == "end") {
    query = IceGrid::QueryPrx::
      uncheckedCast(curr.adapter->getCommunicator()->stringToProxy("FIPA/Query"));
    sniffer = Test::SnifferPrx::
      uncheckedCast(query->findObjectById
		    (curr.adapter->getCommunicator()->stringToIdentity("Sniffer")));
    sniffer->endTest("user");
  }
}
 
void
AgentI::dfAdv
(FIPA::DFAction act,
 const FIPA::DfAgentDescription& desc, 
 const Ice::Current&)
{
}

void
AgentI::destroy
(const Ice::Current& curr)
{
  IceUtil::Mutex::Lock lock(_m);
  
  if (isZombie())
    throw Ice::ObjectNotExistException(__FILE__, __LINE__);
  _destroyed = true;

  // Unsubscribe with the DF.
  _df->unsubscribe(FIPA::AgentPrx::uncheckedCast
		   (curr.adapter->createIndirectProxy(curr.id)));
  // Deregister with the DF and the AMS.
  _df->deregister(curr.id);
  _ams->deregister(curr.id);

  // Remove the servant from the object adapter.
  curr.adapter->remove(curr.id);
}

bool
AgentI::isZombie()
{
  return _destroyed;
}
